package com.dreamoo.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dreamoo.common.Constant;
import com.dreamoo.common.exception.BusinessException;
import com.dreamoo.common.util.TokenUtil;
import com.dreamoo.common.pojo.dto.UserLoginDTO;
import com.dreamoo.common.pojo.entity.User;
import com.dreamoo.common.pojo.vo.UserLoginVO;
import com.dreamoo.common.result.ResultCode;
import com.dreamoo.mapper.UserMapper;
import com.dreamoo.service.UserService;
import com.dreamoo.service.factory.UserLoginFactory;
import com.dreamoo.service.strategy.login.UserLoginStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author 山顶洞人郑某
 * @className UserServiceImpl.java
 * @date 2025 05 08
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserLoginFactory userLoginFactory;

    /**
     * 用户登录
     *
     * @param userLoginDTO 用户登录参数
     * @return token JWT密钥
     */
    @Override
    public String login(UserLoginDTO userLoginDTO) {
        if (Objects.isNull(userLoginDTO)) {
            throw new BusinessException(ResultCode.PARAM_MISS);
        }
        //通过不同的方式登录 采用工厂+策略模式实现解耦
        UserLoginStrategy userLoginStrategy = userLoginFactory.getUserLoginStrategy(userLoginDTO.getLoginType());
        //调用登录方法获取用户信息
        UserLoginVO userLoginVO = userLoginStrategy.userLogin(userLoginDTO);

        //生成Token 并返回给前端
        if (Objects.isNull(userLoginVO)) {
          throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }
        //生成Token返回给前端
        Map<String, Object> map = new HashMap<>(8);
        map.put(Constant.USER_ID,userLoginVO.getId());
        String token = TokenUtil.createToken
                (IdUtil.getSnowflakeNextIdStr(), JSON.toJSONString(map),
                        Constant.TOKEN_EXPIRE_TIME, Constant.TOKEN_SECRET);
        log.info("用户登录成功，生成Token:" + token);
        return token;
    }
}
